#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <unistd.h>


#include <ctime>

using namespace ThreadModule;

using ringqueue_t = RingQueue<Task>;

void Productor(ringqueue_t &rq, std::string& name)
{
    // std::cout << "Productor" << std::endl;
    int cnt = 1;
    while (true)
    {
        sleep(1);
        // 1. 获取任务
        // 2. 生产任务
        rq.Enqueue(Download);
        std::cout << "Productor : " << cnt <<  " [" << name << "]" << std::endl;
        cnt++;
    }
}

void Consumer(ringqueue_t &rq, std::string& name)
{
    // std::cout << "Consumer" << std::endl;
    while (true)
    {
        // int data = 0;
        // 1. 消费任务
        Task t;
        rq.Pop(&t);
        std::cout << "Consumer : "  << " [" << name << "]" << std::endl;
        // 2. 处理任务
        t();
        // sleep(1);
    }
}

void InitComm(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq, func_t<ringqueue_t> func, const std::string& who)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1) + "-" + who;
        threads->emplace_back(func, rq, name);
        // threads->back().Start();
    }
}

void InitProductor(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Productor, "Productor");
}

void InitConsumer(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Consumer, "cousumer");
}

void WaitAlltrhead(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

void StartAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread:threads)
    {
        std::cout << "start: " << thread.name() << std::endl;
        thread.Start();
    }
}

int main()
{
    // 阻塞队列
    ringqueue_t *rq = new ringqueue_t(5);
    std::vector<Thread<ringqueue_t>> threads;

    InitProductor(&threads, 1, *rq);
    InitConsumer(&threads, 3, *rq);

    StartAll(threads);
    WaitAlltrhead(threads);
    return 0;
}

// using namespace ThreadModule;

// void Productor(BlockQueue<int>* &bq)
// {
//     // int cnt = 1;
//     while (true)
//     {
//         bq->Enqueue(1);
//         std::cout << "Productor prodect data:" << std::endl;
//         // cnt++;
//         sleep(1);
//     }
// }

// void Consumer(BlockQueue<int>* &bq)
// {
//     while (true)
//     {
//         int data;
//         bq->Pop(&data);
//         std::cout << "Consumer consume data:"<< data << std::endl;
//     }
// }

// void StartComm(std::vector<Thread<BlockQueue<int>*>> *threads, int num, BlockQueue<int>* bq, func_t<BlockQueue<int>*> func)
// {
//     for (int i = 0; i < num; i++)
//     {
//         std::string name = "thread-" + std::to_string(i + 1);
//         threads->emplace_back(Productor, bq, name);
//         threads->back().Start();
//     }
// }

// void StartProductor(std::vector<Thread<BlockQueue<int>*>> *threads, int num, BlockQueue<int>* bq)
// {
//     StartComm(threads, num, bq, Productor);
// }

// void StartConsumer(std::vector<Thread<BlockQueue<int>*>> *threads, int num, BlockQueue<int>* bq)
// {
//     StartComm(threads, num, bq, Consumer);
// }

// void WaitAlltrhead(std::vector<Thread<BlockQueue<int>*>> &threads)
// {
//     for (auto &thread : threads)
//     {
//         thread.Join();
//     }
// }

// int main()
// {
//     //阻塞队列
//     BlockQueue<int>* bq = new BlockQueue<int>(5);//坑点，Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,v
//     std::vector<Thread<BlockQueue<int>*>> threads;

//     StartProductor(&threads, 1, bq);//这里bq是值传递Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,Bug,
//     StartConsumer(&threads, 1, bq);
//     WaitAlltrhead(threads);
//     return 0;
// }